home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <setjmp.h>
- #include "apm.h"
-
- extern void exit();
- extern long strtol();
- extern long time();
-
- #ifndef MSC
- extern char *malloc();
- extern char *realloc();
- extern void free();
- #endif /* ! MSC */
-
- #ifdef MSDOS
- # define STRING_SIZE 512
- #else
- # define STRING_SIZE 8192
- #endif /* MSDOS */
-
- jmp_buf here;
-
- /*
- * System-independent replacement for index() and strchr().
- */
- char *
- sindex(s, ch)
- char *s;
- int ch;
- {
- if (s != NULL) {
- for (; *s != '\0'; ++s) {
- if (*s == (char)ch) {
- return (s);
- }
- }
- }
- return (NULL);
- }
-
- int
- errorHandler(error, message, file, line, func)
- int error;
- char *message;
- char *file;
- int line;
- char *func;
- {
- fprintf(stderr, "\"%s\": line %d: %s: %s %d: %s\n",
- file, line, func, error < 0 ? "error" : "warning",
- error, message);
- if (error < 0) {
- longjmp(here, 1);
- }
- else {
- return (error);
- }
- }
-
- void
- usage()
- {
- fprintf(stderr, "usage: apm [base]\n");
- exit(1);
- }
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- APM apm;
- APM other;
- APM result;
- APM remainder;
- char *cp;
- char *x;
- int ercode;
- int scaleFactor;
- int n;
- int outLen;
- int outDp;
- int leftjust = 0;
- int columnlist = 0;
- short base = -1;
-
- for (--argc, ++argv; argc > 0; --argc, ++argv) {
- if (base > -1) {
- usage();
- }
- base = (short)strtol(*argv, &cp, 10);
- }
-
- if (argc > 0) {
- usage();
- }
-
- if (base == -1) {
- base = 0;
- }
-
- apmDebugFile(stderr);
- (void)apmErrorFunc(errorHandler);
-
- if (setjmp(here) != 0) {
- exit (1);
- }
-
- x = malloc(STRING_SIZE + 1);
-
- if (x == NULL) {
- fprintf(stderr, "not enough memory\n");
- exit(1);
- }
-
- apm = apmNew(0);
- other = apmNew(0);
- result = apmNew(0);
- remainder = apmNew(0);
-
- for (;;) {
- setjmp(here);
- /***
- apmGarbageCollect();
- ***/
- fprintf(stderr, "\nEnter first number:\t");
- fflush(stderr);
- if (fgets(x, STRING_SIZE, stdin) == NULL) {
- break;
- }
- cp = sindex(x, '\n');
- if (cp != NULL) {
- *cp = '\0';
- }
- if (x[0] == '\0') {
- apmAssign(apm, result);
- }
- else {
- apmAssignString(apm, x, base);
- }
-
- fprintf(stderr, "Enter second number:\t");
- fflush(stderr);
- if (fgets(x, STRING_SIZE, stdin) == NULL) {
- break;
- }
- cp = sindex(x, '\n');
- if (cp != NULL) {
- *cp = '\0';
- }
- if (x[0] == '\0') {
- apmAssign(other, result);
- }
- else {
- apmAssignString(other, x, base);
- }
-
- fprintf(stderr, "Enter scale factor:\t");
- fflush(stderr);
- if(fgets(x, STRING_SIZE, stdin) == NULL) {
- break;
- }
- cp = sindex(x, '\n');
- if (cp != NULL) {
- *cp = '\0';
- }
- scaleFactor = (int)strtol(x, &cp, 10);
- if (cp == x) {
- scaleFactor = 0;
- }
-
- fprintf(stderr, "Enter field width:\t");
- fflush(stderr);
- if(fgets(x, STRING_SIZE, stdin) == NULL) {
- break;
- }
- cp = sindex(x, '\n');
- if (cp != NULL) {
- *cp = '\0';
- }
- outLen = (int)strtol(x, &cp, 10);
- if (cp == x) {
- outLen = 32;
- }
-
- fprintf(stderr, "Enter number of DP's:\t");
- fflush(stderr);
- if(fgets(x, STRING_SIZE, stdin) == NULL) {
- break;
- }
- cp = sindex(x, '\n');
- if (cp != NULL) {
- *cp = '\0';
- }
- outDp = (int)strtol(x, &cp, 10);
- if (cp == x) {
- outDp = 10;
- }
-
- n = apmCompare(apm, other);
- if (n < 0) {
- cp = "<";
- }
- else if (n > 0) {
- cp = ">";
- }
- else {
- cp = "==";
- }
- fprintf(stderr, " Comparison:\t\tfirst %s second\n", cp);
-
- /*
- apmNegate(result, apm);
- */
- apmCalc(result, apm, APM_NEG, NULL);
- apmConvert(x, outLen + 1, outDp, 0, leftjust, result);
- if (columnlist) {
- fprintf(stderr, "\t\t\t12345678901234567890123456789012345678901234567890123456789012345678901234567890\n");
- }
- fprintf(stderr, " Negation of first:\t%s\n", x);
-
- cp = NULL;
- /*
- apmReciprocal(result, outDp, other);
- */
- apmCalc(result, other, APM_RECIP(outDp), NULL);
- if (apm_errno == APM_WDIVBYZERO) {
- cp = " (division by zero)";
- }
- apmConvert(x, outLen + 1, outDp, 0, leftjust, result);
- fprintf(stderr, " Reciprocal of second:\t%s%s\n", x,
- cp == NULL ? "" : cp);
-
- /*
- apmAdd(result, apm, other);
- */
- apmCalc(result, apm, other, APM_ADD, NULL);
- apmConvert(x, outLen + 1, outDp, 0, leftjust, result);
- fprintf(stderr, " Sum:\t\t\t%s\n", x);
-
- /*
- apmSubtract(result, apm, other);
- */
- apmCalc(result, apm, other, APM_SUB, NULL);
- apmConvert(x, outLen + 1, outDp, 0, leftjust, result);
- fprintf(stderr, " Difference:\t\t%s\n", x);
-
- /*
- apmMultiply(result, apm, other);
- */
- apmCalc(result, apm, other, APM_MUL, NULL);
- apmConvert(x, outLen + 1, outDp, 0, leftjust, result);
- fprintf(stderr, " Product:\t\t%s\n", x);
-
- cp = NULL;
- /*
- apmDivide(result, outDp, remainder, apm, other);
- */
- apmCalc(result, apm, other, APM_DIV(outDp), NULL);
- apmGetRegister(remainder, 0);
- if (apm_errno == APM_WDIVBYZERO) {
- cp = " (division by zero)";
- }
- apmConvert(x, outLen + 1, outDp, 0, leftjust, result);
- fprintf(stderr, " Quotient:\t\t%s%s\n", x,
- cp ? cp : "");
- apmConvert(x, outLen + 1, outDp, 0, leftjust, remainder);
- fprintf(stderr, " Remainder:\t\t%s\n", x);
-
- /*
- apmScale(apm, result, scaleFactor);
- */
- apmCalc(apm, apm, APM_POP(1), result, APM_SCALE(scaleFactor),
- NULL);
- apmConvert(x, outLen + 1, outDp, 0, leftjust, apm);
- fprintf(stderr, " Scaled quotient:\t%s\n", x);
-
- apmCalc(result, APM_PUSH(1), APM_DUP, APM_ADD, APM_DUP,
- other, APM_MUL, APM_SUB, NULL);
- apmConvert(x, outLen + 1, outDp, 0, leftjust, result);
- fprintf(stderr, " Calc test:\t\t%s\n", x);
-
- }
- putchar('\n');
- }
-